package oop.core.map;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import oop.core.entity.*;
import oop.core.area.*;
import oop.core.item.*;
import oop.core.visitors.*;
import oop.core.skill.SkillObject;
import oop.core.view.Renderable;

import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.File;

/**
 * The class that contains all the mapdata, using hashmaps to key objects to locations.
 */
public class GameMap
{
	private Avatar player;
	private String name;
	private List<Entity> entityList;
	private Map<Location, Terrain> terrainMap;
	private Map<Location, AreaEffect> aeMap;
	private Map<Location, TakeableItem> takeableItemMap;
	private Map<Location, ObstacleItem> obstacleItemMap;
	private Map<Location, InteractiveItemVisitable> interactiveItemVisitableMap;
	private Map<Location, Decal> decalMap;
	private Map<Location, SkillObject> skillObjectMap;
	
	
	/**
	 * Default GameMap to test
	 */
	
	public GameMap()
	{
		
		ArrayList<MovementType> list = new ArrayList<MovementType>();
		list.add(MovementType.walk);
		player = new Avatar(1000, new Occupation("Smasher", null, null, null, new Stats(100,10,10,10,10,10,10,10,10)), "smasherE", "Avatar", 0, new Location(25, 25), true, new Equipment(), new Inventory(), list, new DerivedStats(100,10,10,10,10,10,10,10,10));
		String libraryPath = "assets/library/Items.txt";
		String terrainParserPath = "assets/maps/world/map.txt";
		String decalParserPath = "assets/maps/world/decal.txt";
		String areaEffectParserPath = "assets/maps/world/AE.txt";
		String takeableItemParserPath = "assets/maps/world/takeableItem.txt";
		String obstaclePath = "assets/maps/world/obstacles.txt";
		String interactivePath = "assets/maps/world/interactives.txt";
		MapParser.loadingImageLibrary(libraryPath);
		this.terrainMap = MapParser.terrainParser(terrainParserPath);
		this.decalMap = MapParser.decalParser(decalParserPath);
		this.aeMap = MapParser.areaEffectParser(areaEffectParserPath);
		this.takeableItemMap = MapParser.parseLocationToItem(takeableItemParserPath);
		this.obstacleItemMap = MapParser.obstacleItemParser(obstaclePath);
		this.interactiveItemVisitableMap = MapParser.interactiveItemParser(interactivePath);
		skillObjectMap = new HashMap<Location, SkillObject>();
		entityList = new ArrayList<Entity>();
	}
	
	/**
	 * @param player A reference to the player
	 * @param name The name of the map, that will be used as a key for hashing
	 */
	public GameMap(Avatar player, String name) {
		this.player = player;
		this.name = name;
		terrainMap = new HashMap<Location, Terrain>();
		aeMap = new HashMap<Location, AreaEffect>();
		takeableItemMap = new HashMap<Location, TakeableItem>();
		obstacleItemMap = new HashMap<Location, ObstacleItem>();
		interactiveItemVisitableMap = new HashMap<Location, InteractiveItemVisitable>();
		decalMap = new HashMap<Location, Decal>();
		skillObjectMap = new HashMap<Location, SkillObject>();
	}

	public List<Entity> getEntityList() {
		return entityList;
	}

	public void setPlayer(Avatar player) {
		this.player = player;
	}

	public Map<Location, Terrain> getTerrainMap() {
		return terrainMap;
	}

	public Map<Location, AreaEffect> getAeMap() {
		return aeMap;
	}

	public Map<Location, TakeableItem> getTakeableItemMap() {
		return takeableItemMap;
	}
	
	public Map<Location, ObstacleItem> getObstacleItemMap() {
		return obstacleItemMap;
	}
	
	public Map<Location, Decal> getDecalMap() {
		return decalMap;
	}
	
	public Map<Location, SkillObject> getSkillObjectMap()
	{
		return skillObjectMap;
	}
	
	public Map<Location, InteractiveItemVisitable> getInteractiveItemVisitableMap()
	{
		return interactiveItemVisitableMap;
	}

	public Avatar getPlayer() {
		return player;
	}

	public String getName() {
		return name;
	}
	
	/**
	 * Adds an entity to the GameMap's list of entities
	 * @param ent The entity added
	 */
	public void addEntity(Entity ent)
	{
		entityList.add(ent);
	}
	
	/**
	 * Adds an item to the GameMap's map of items
	 * @param loc Where the item is located
	 * @param elem The item added to the map of items
	 */
	public void addTakeableItem(Location loc, TakeableItem elem)
	{
		takeableItemMap.put(loc, elem);
	}
	
	public void addObstacleItem(Location loc, ObstacleItem elem)
	{
		obstacleItemMap.put(loc, elem);
	}
	
	public void addInteractiveItemVisitable(Location loc, InteractiveItemVisitable elem)
	{
		interactiveItemVisitableMap.put(loc,elem);
	}
	
	/**
	 * Adds a terrain to the GameMap's map of terrains
	 * @param loc Where the terrain is located
	 * @param elem The terrain added to the map of terrains
	 */
	public void addTerrain(Location loc, Terrain elem)
	{
		terrainMap.put(loc, elem);
	}
	
	/**
	 * Adds a decal to the GameMap's list of decals
	 * @param loc Where the decal is located
	 * @param elem The decal added to the map of decals
	 */
	public void addDecal(Location loc, Decal elem)
	{
		decalMap.put(loc, elem);
	}
	
	/**
	 * Adds an AreaEffect to the GameMap's list of AEs
	 * @param loc Where the AreaEffect is located
	 * @param elem The AE added to the map of AEs
	 */
	public void addAreaEffect(Location loc, AreaEffect elem)
	{
		aeMap.put(loc, elem);
	}
	
	public Terrain getTerrainAt(Location loc)
	{
		return terrainMap.get(loc);
	}
	
	public Decal getDecalAt(Location loc)
	{
		return decalMap.get(loc);
	}
	
	public TakeableItem getTakeableItemAt(Location loc)
	{
		return takeableItemMap.get(loc);
	}
	
	public ObstacleItem getObstacleItemAt(Location loc)
	{
		return obstacleItemMap.get(loc);
	}
	public InteractiveItemVisitable getInteractiveItemVisitableAt(Location loc)
	{
		return interactiveItemVisitableMap.get(loc);
	}
	
	public AreaEffect getAreaEffectAt(Location loc)
	{
		return aeMap.get(loc);
	}
	
	public SkillObject getSkillObjectAt(Location loc)
	{
		return skillObjectMap.get(loc);
	}

	public Entity getEntity(Location loc)
	{
		Entity ret = null;
		for(Entity e: entityList)
		{
			if((e.getLoc()).equals(loc))
			{
				ret = e;
				break;
			}		
		}
		return ret;
	}
	//Move all parsing methods to MapParser.java
    
    
    
}
